﻿using System.Diagnostics;
using UnityEngine;
using UnityEngine.SceneManagement;

public class LoadEvent : ZEvent
{
    public int rate;
    public LoadEvent(string type, int rate) : base(type)
    {
        this.rate = rate;
    }
}

public struct SceneName
{
    public const string LEVEL_0 = "Empty";
    public const string LEVEL_1 = "Loading";
    public const string LEVEL_2 = "LoginView";
    public const string LEVEL_3 = "Main";
}

public class SceneMgr : IZUpdate, IBaseData
{
    private readonly int SceneResPer = 80;
    private readonly int ScenePer = 20;
    Stopwatch stopwatch = new Stopwatch();

    public LoadEvent loadEvent;
    public AsyncOperation op;
    public bool isloading;
    public bool isInit;

    public string curSceneName;
    private int maxProgress;
    public float toProgress;
    public float displayProgress;

    private float curTime;
    private float lastTime;
    private float minTime = 1f;
    
    public void Init()
    {
        if (!isInit)
        {
            isInit = true; curSceneName = Application.loadedLevelName;
            loadEvent = new LoadEvent(ConstData.PROGRESS_UPDATE, 1);
            ZEventCenter.DispatchEvent(new ZEvent(ConstData.SCENE_LOAD_END));
        }
    }

    /// <summary>
    /// 加载场景
    /// <param name="sceneName"></param>
    public void LoadScene(string sceneName, bool showLoading = true, float minTime = 1)
    {
        if (isloading)
        {
            EDebug.LogError("当前正在加载其它场景..请求加载失败" + sceneName);
            return;
        }
        isloading = true;

        if (ZMgr.AppMgr.sceneEffect != null)
        {
            ZMgr.AppMgr.sceneEffect.Clear();
        }
        EDebug.Log("开始Loading " + LockType.SceneLoading);
        UIInputMgr.GetSingleton().LockInput(LockType.SceneLoading);
        SceneManager.LoadScene("loading");

        //1、清理所有缓存资源，结束所有加载，停止所有的协程
        ZMgr.ResourceMgr.Clear();
        //2、打开加载场景进度条
        if (showLoading)
        {
            LoadingMgr.GetSingleton().Open();
        }
        ZMgr.TimerMgr.SetTimeOut<object>(LaodSceneRun, 0.2f, sceneName, minTime);
    }
    
    private void LaodSceneRun(object[] arg)
    {
        string sceneName = (string)arg[0];
        minTime = (float)arg[1];
        
        stopwatch.Reset();
        stopwatch.Start();

        //3、关闭并销毁所有打开的界面
        ZEventCenter.DispatchEvent(new ZEvent(ConstData.SCENE_LOAD_START));
        stopwatch.Stop(); Time.timeScale = 1;
        toProgress = displayProgress = 0;
        stopwatch.Reset(); stopwatch.Start();

        ZEventCenter.AddEventListener(ConstData.PROGRESS_OK, LoadComplete);
        //4、验证场景是否赛场场景，是 发起场景所用资源加载，车库场景加载车库所需资源；
        if (sceneName == SceneName.LEVEL_3)
        {
            ZMgr.ResourceMgr.LoadResByMainScene(sceneName);
            //ZMgr.ResourceMgr.LoadResByInterfaceScene(sceneName);
        }
        else
        {
            ZMgr.ResourceMgr.LoadResByGameScene(sceneName);
        }
        Application.targetFrameRate = 60;
        curSceneName = sceneName; lastTime = 0;
        UpdateMgr.GetSingleton().AddUpdate(this);
    }

    public void LoadComplete(ZEvent ev)
    {
        op = null;
        UIInputMgr.GetSingleton().UnLockInput(LockType.SceneLoading);
        Application.targetFrameRate = 30;
        curSceneName = Application.loadedLevelName;
        UpdateMgr.GetSingleton().RemoveUpdate(this);

        LoadingMgr.GetSingleton().Close(); isloading = false;
        ZEventCenter.RemoveEventListener(ConstData.PROGRESS_OK, LoadComplete);
        ZEventCenter.DispatchEvent(new ZEvent(ConstData.SCENE_LOAD_END));
    }
    
    public void ZUpdate()
    {
        curTime = Time.realtimeSinceStartup;
        if (lastTime == 0) { lastTime = curTime; }

        float value = (curTime - lastTime) * 100;
        displayProgress = displayProgress + value / minTime;
        lastTime = curTime;

        if (!ZMgr.ResourceMgr.IsLoaded)     //加载完
        {
            toProgress = ZMgr.ResourceMgr.LoadProgress * SceneResPer;
        }
        else if (op == null)                //开始加载
        {
            stopwatch.Stop();
            //5、场景所有资源加载成功后，开始加载场景文件
            op = SceneManager.LoadSceneAsync(curSceneName);
            op.allowSceneActivation = false;
        }
        else    
        {
            //正在加载
            toProgress = op.progress * ScenePer + SceneResPer;
            if (op.isDone) { toProgress = 100f; }
            else if (op.allowSceneActivation == false)
            {
                if (toProgress >= 89)
                {
                    toProgress = 95f;
                }
                if (toProgress >= 89 && displayProgress >= 95)
                {
                    toProgress = 99f;
                    op.allowSceneActivation = true;
                }
            }
        }
        
        if (displayProgress > toProgress)
        {
            displayProgress = toProgress;
        }

        loadEvent.rate = Mathf.RoundToInt(displayProgress);
        if (loadEvent.rate > maxProgress)
        {
            ZEventCenter.DispatchEvent(loadEvent);
            maxProgress = loadEvent.rate;
        }
        if (displayProgress == 100)
        {
            ZEventCenter.DispatchEvent(new ZEvent(ConstData.PROGRESS_OK));
            maxProgress = 0;
        }
    }
}